<?php
declare(strict_types=1);
/**
 * 异步线程队列
 * 协程处理
 * TaskServer
 */

namespace Service\ExtraService;

use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\WaitGroup;
use Service\BaseService;
use Hyperf\Task\Annotation\Task;
use App\Model\BbcLogModel\MicroServiceLog;
use Service\HttpServer\HttpCurl;

class TaskWorker extends BaseService {
    /**
     * Task
     * 进行协程并发调用http请求
     * @param array $data
     */
    public function handle($data = []) {
        $result = [];
        $count  = count($data);
        $wg     = new WaitGroup();
        $wg->add($count);
        foreach ($data as $key => $val) {
            co(function () use ($wg, $key, $val, & $result) {
                $start_time   = microtime(true);
                $res          = HttpCurl::instance()->apiRequest($val['url'], $val['data'], $val['method'], $val['format'], $val['header'] ?? [],$val['cert']??[]);
                $used_time    = bcsub((string)microtime(true), (string)$start_time, 3);
                $result[$key] = [
                    'request'   => $val,
                    'response'  => $res,
                    'used_time' => $used_time,
                ];

                $response_data = !empty($res['result']) ? json_decode($res['result'], true) : [] ;
                $response_data = !empty($response_data) ? json_encode($response_data, JSON_UNESCAPED_UNICODE) : $res['result'];
                //写入日志
                MicroServiceLog::instance()->add([
                    'id'             => IdService::instance()->getLogID(),
                    'interface_code' => $val['tag'],
                    'request_url'    => $val['url'],
                    'request_param'  => json_encode($val['data'], JSON_UNESCAPED_UNICODE),
                    'response_code'  => $res['httpCode'],
                    'response_data'  => $response_data,
                    'req_used_time'  => $used_time,
                    'cd'             => time()
                ]);
                $wg->done();
            });
        }

        $wg->wait();
        return $result;
    }

    /**
     * 加入异步队列池
     * @param array $param
     * @return mixed
     */
    public function addTask($data = [], $taskMethod = 'handle') {
        $container = ApplicationContext::getContainer();
        $task      = $container->get(TaskWorker::class);
        return $task->{$taskMethod}($data);
    }
}